/*
    Copyright 2006 Andrew Wilkinson <andrew@indiegigs.co.uk>

    This file is part of libgp2x.

    libgp2x is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    libgp2x is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with libgp2x; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <stdio.h>
#include <string.h>

#include "gp2x_internal.h"

void GP2x_940_load(char* filename) {
    FILE* fp;
    unsigned char buf[1024];
    size_t bytes;
    size_t read = 0;

    GP2x_940_pause();
    GP2x_940_reset();

    fp = fopen(filename, "r");
    if(fp < 0) {
        fprintf(stderr, "Libgp2x: Unable to load file %s onto the 940t.\n", filename);
        return;
    }

    while((bytes = fread(buf, 1, 1024, fp))) {
        memcpy((unsigned char*)(GP2x_upper_memory+read), buf, bytes);
        read += bytes;
    }
    fprintf(stderr, "Libgp2x: Loaded %i bytes of %s onto the 940t.\n", read, filename);

    GP2x_register(GP2x_REG_940_INTERRUPT_1) = 0;
    GP2x_register(GP2x_REG_940_INTERRUPT_2) = 0;

    GP2x_940_unpause();
    GP2x_940_enable();
}

void GP2x_940_setup() {
    GP2x_940_running = 0; 
    GP2x_940_reset();
    GP2x_940_pause();
}

void GP2x_940_shutdown() {
    GP2x_940_running = 0;
    GP2x_940_reset();
    GP2x_940_pause();
}

void GP2x_940_pause() {
    GP2x_940_running = 0;
    GP2x_register(GP2x_REG_940_CONTROL) &= (~(1<<0));
}

void GP2x_940_unpause() {
    GP2x_940_running = 1;
    GP2x_register(GP2x_REG_940_CONTROL) |= (1<<0);
}

void GP2x_940_enable() {
    GP2x_940_running = 1;
    // The 2 is the memory address shift
    GP2x_register(GP2x_REG_940_MEMORY_BASE) = 2;
}

void GP2x_940_reset() {
    GP2x_940_running = 0;
    // (1<<7) forces the 940 into reset
    // The 2 is the memory address shift
    GP2x_register(GP2x_REG_940_MEMORY_BASE) = (1<<7) | 2;
}
